package com.w3c.pragmatic.controller;

import com.w3c.pragmatic.domain.Response;
import com.w3c.pragmatic.threadpool.CustomerThreadPool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池控制 前端控制器
 *
 * @author wangdong
 * @since 2025-02-20
 */
@Slf4j
@RestController
@RequestMapping("/thread")
@Api(tags = "线程池控制控制层ThreadPoolController")
public class ThreadPoolController {

  @Resource private ThreadPoolExecutor commonThreadExecutor;

  /**
   * 方案一：自定义线程池（这里的线程池每次创建所以用完药关闭）
   *
   * @return String 成功描述
   */
  @ApiOperation(value = "自定义线程池", httpMethod = "GET")
  @RequestMapping(
      value = "/customer",
      method = RequestMethod.GET,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public Response<String> doCustomerThreadPool() {
    long startTime = System.currentTimeMillis();
    // 创建线程池
    ThreadPoolExecutor threadPoolExecutor = new CustomerThreadPool().createCustomerThreadPool();
    // 循环创建线程加入线程池中执行
    for (int i = 0; i < 13; i++) {
      threadPoolExecutor.execute(
          new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
              log.info("当前线程={}", Thread.currentThread().getId());
              TimeUnit.SECONDS.sleep(10);
            }
          });
    }
    // 关闭线程池(如果是长期使用这里可以不用关闭)
    // 因为这里是异步执行，shutdown()不会立马执行，而是等所有线程执行完后才会执行
    log.info("所有线程执行完毕,总耗时={}ms, 关闭线程池!", System.currentTimeMillis() - startTime);
    threadPoolExecutor.shutdown();
    return Response.ok();
  }

  /**
   * 方案二：全局公共线程池（这里的线程池全局初始化一份，用完禁止关闭）
   *
   * @return String 成功描述
   */
  @ApiOperation(value = "全局初始化线程池", httpMethod = "GET")
  @RequestMapping(
      value = "/common",
      method = RequestMethod.GET,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public Response<String> doCommonThreadPool() {
    long startTime = System.currentTimeMillis();
    // 创建线程池
    // 循环创建线程加入线程池中执行
    for (int i = 0; i < 13; i++) {
      commonThreadExecutor.execute(
          new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
              TimeUnit.SECONDS.sleep(10);
              log.info("当前线程={}", Thread.currentThread().getId());
            }
          });
    }
    // 公共线程池不要关闭！！！
    log.info("所有线程执行完毕,总耗时={}ms!", System.currentTimeMillis() - startTime);
    return Response.ok();
  }
}
